package com.eat.fish_service.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.eat.common_utils.R;
import com.eat.fish_service.entity.DTO.StateCount;
import com.eat.fish_service.entity.DTO.TypeCount;
import com.eat.fish_service.entity.Dao.Aquarium;
import com.eat.fish_service.entity.Dao.FishNum;
import com.eat.fish_service.entity.Dao.SensorData;
import com.eat.fish_service.entity.VO.FishCountStaVo;
import com.eat.fish_service.entity.VO.FishCountVo;
import com.eat.fish_service.mapper.FishMapper;
import com.eat.fish_service.mapper.FishNumMapper;
import com.eat.fish_service.service.AquariumService;
import com.eat.fish_service.service.FishNumService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eat.fish_service.service.FishService;
import com.eat.fish_service.service.SensorDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author CZF
 * @since 2022-04-26
 */
@Service
@Slf4j
public class FishNumServiceImpl extends ServiceImpl<FishNumMapper, FishNum> implements FishNumService {

    @Autowired
    FishService fishService;

    @Autowired
    FishMapper fishMapper;

    @Autowired
    AquariumService aquariumService;

    @Autowired
    SensorDataService sensorDataService;

    @Autowired
    FishNumMapper fishNumMapper;




    @Override
    public R increaseAndDecrease(Long aquariumId, Integer dayCount) {
        //查询表中记录的 由年月日分组 的 组数
        Integer allCount = fishNumMapper.fishCountGroupByDate(aquariumId);
//        log.info(allCount.toString());

        List<FishNum> fishNumList = baseMapper.selectList(new QueryWrapper<FishNum>().select("fish_num", "gmt_create").eq("aquariumId", aquariumId));
//        log.info(fishNumList.toString());


        List<String> xAxis = fishNumMapper.xAxis(aquariumId, allCount);//查询出每一天的变化
//        log.info(xAxis.toString());

        //增加情况
        List<Integer> yAxis1 = new ArrayList<>(fishNumList.size());  //增
        List<Integer> yAxis2 = new ArrayList<>(fishNumList.size());  //减

        int last = 0;
        for (int i = 0; i < xAxis.size(); i++) {
            List<Integer> fishNums = fishNumMapper.yAxis(aquariumId, xAxis.get(i));
            if (i == 0) {
                int increase = 0;
                int decrease = 0;
                for (int j = 0; j < fishNums.size(); j++) {
                    if (j == 0) {
                        increase += fishNums.get(0);
                    } else if (fishNums.get(j) > fishNums.get(j - 1)) {
                        increase += fishNums.get(j) - fishNums.get(j - 1);
                    } else if (fishNums.get(j) < fishNums.get(j - 1)) {
                        decrease += fishNums.get(j - 1) - fishNums.get(j);
                    }
                }
                yAxis1.add(increase);
                yAxis2.add(decrease);
            } else {
                int increase = 0;
                int decrease = 0;
                for (int j = 0; j < fishNums.size(); j++) {
                    if (j == 0) {
                        if (fishNums.get(0) >= last) {
                            increase += fishNums.get(0) - last;
                        } else if (fishNums.get(0) < last) {
                            decrease += last - fishNums.get(0);
                        }
                    } else if (fishNums.get(j) > fishNums.get(j - 1)) {
                        increase += fishNums.get(j) - fishNums.get(j - 1);
                    } else if (fishNums.get(j) < fishNums.get(j - 1)) {
                        decrease += fishNums.get(j - 1) - fishNums.get(j);
                    }
                }
                yAxis1.add(increase);
                yAxis2.add(decrease);
            }
            last = fishNums.get(fishNums.size() - 1);
        }

        if (dayCount < allCount) {//如果要查询的天数小于所有的天数，则删除不必要的天数
            int needRemove = allCount - dayCount;
            for (int i = 0; i < needRemove; i++) {
                xAxis.remove(0);
                yAxis1.remove(0);
                yAxis2.remove(0);
            }
        }

        return R.ok().data("xAxis", xAxis).data("yAxis1", yAxis1).data("yAxis2", yAxis2);
    }

    @Override
    public R fishCountSta(Long aquariumId, Integer count) {

        QueryWrapper<FishNum> wrapper = new QueryWrapper<>();
        wrapper.eq("aquariumId", aquariumId);
        wrapper.orderByDesc("gmt_create");
        wrapper.last("limit " + count);
        wrapper.orderByAsc("gmt_create");

        List<FishNum> fishNums = baseMapper.selectList(wrapper);
        Collections.reverse(fishNums);
        FishCountVo fishCountVo = new FishCountVo();
        for (FishNum fishNum : fishNums) {
            fishCountVo.getXAxis().add(fishNum.getGmtCreate());
            fishCountVo.getYAxis().add(fishNum.getFishNum());
        }
        return R.ok().data("fishCountVo", fishCountVo);
    }

    @Override
    public R fishProportion(Long aquariumId) {
        //每种类型的鱼对应的数量
        List<TypeCount> typeCounts = fishMapper.selectTypeCount(aquariumId);
        //返回给前端的玫瑰图数组
        List<FishCountStaVo> resList = new ArrayList<>();


        int total = 0;
        for (TypeCount typeCount : typeCounts) {
            total += typeCount.getCount();
            FishCountStaVo fishCountStaVo = new FishCountStaVo();
            fishCountStaVo.setValue(typeCount.getCount());
            fishCountStaVo.setName(typeCount.getType());
            resList.add(fishCountStaVo);
        }

        for (FishCountStaVo fishCountStaVo : resList) {
            fishCountStaVo.setName(fishCountStaVo.getName() + " " + Math.round(fishCountStaVo.getValue().floatValue() / total * 100) + "%");
//            log.info(fishCountStaVo.getName());
        }

        return R.ok().data("resList", resList);
    }

    @Override
    public R fishProgress(Long aquariumId) {
        Aquarium aquarium = aquariumService.getById(aquariumId);

        List<StateCount> stateCountList = fishMapper.selectStateCount(aquariumId);

        Long count1 = stateCountList.stream().filter(stateCount -> stateCount.getName().equals("良好")).count();
        Long count2 = stateCountList.stream().filter(stateCount -> stateCount.getName().equals("生病")).count();
        Long count3 = stateCountList.stream().filter(stateCount -> stateCount.getName().equals("死亡")).count();

        stateCountList.clear();

        stateCountList.add(new StateCount(count1.intValue(), "良好"));
        stateCountList.add(new StateCount(count2.intValue(), "生病"));
        stateCountList.add(new StateCount(count3.intValue(), "死亡"));

        return R.ok()
                .data("curCount", aquarium.getFishNum())
                .data("maxCount", aquarium.getMaxNum())
                .data("stateCountList", stateCountList);
    }

    @Override
    public R fishStateCircle(Long aquariumId) {
        //每种状态的鱼对应的数量
        List<StateCount> stateCountList = fishMapper.selectStateCount(aquariumId);
        return R.ok().data("stateCountList", stateCountList);
    }

    @Override
    public R oneWeekWaterSta(Long aquariumId) {
        //查询今天开始时间
        Date dayBegin = DateUtil.beginOfDay(new Date());
        String begin = DateUtil.formatDateTime(dayBegin);
        //今天的结束时间
        Date dayEnd = DateUtil.endOfDay(dayBegin);
        String end = DateUtil.formatDateTime(dayEnd);
        List<Float> dayAverage = getDayAverage(begin, end, aquariumId);

        //查询前1天
        Date dayBegin1 = DateUtil.offsetDay(dayBegin, -1);
        String begin1 = DateUtil.formatDateTime(dayBegin1);
        Date dayEnd1 = DateUtil.offsetDay(dayEnd, -1);
        String end1 = DateUtil.formatDateTime(dayEnd1);
        List<Float> dayAverage1 = getDayAverage(begin1, end1, aquariumId);

        //查询前2天
        Date dayBegin2 = DateUtil.offsetDay(dayBegin, -2);
        String begin2 = DateUtil.formatDateTime(dayBegin2);
        Date dayEnd2 = DateUtil.offsetDay(dayEnd, -2);
        String end2 = DateUtil.formatDateTime(dayEnd2);
        List<Float> dayAverage2 = getDayAverage(begin2, end2, aquariumId);

        //查询前3天
        Date dayBegin3 = DateUtil.offsetDay(dayBegin, -3);
        String begin3 = DateUtil.formatDateTime(dayBegin3);
        Date dayEnd3 = DateUtil.offsetDay(dayEnd, -3);
        String end3 = DateUtil.formatDateTime(dayEnd3);
        List<Float> dayAverage3 = getDayAverage(begin3, end3, aquariumId);

        //查询前4天
        Date dayBegin4 = DateUtil.offsetDay(dayBegin, -4);
        String begin4 = DateUtil.formatDateTime(dayBegin4);
        Date dayEnd4 = DateUtil.offsetDay(dayEnd, -4);
        String end4 = DateUtil.formatDateTime(dayEnd4);
        List<Float> dayAverage4 = getDayAverage(begin4, end4, aquariumId);

        //查询前5天
        Date dayBegin5 = DateUtil.offsetDay(dayBegin, -5);
        String begin5 = DateUtil.formatDateTime(dayBegin5);
        Date dayEnd5 = DateUtil.offsetDay(dayEnd, -5);
        String end5 = DateUtil.formatDateTime(dayEnd5);
        List<Float> dayAverage5 = getDayAverage(begin5, end5, aquariumId);

        //查询前6天
        Date dayBegin6 = DateUtil.offsetDay(dayBegin, -6);
        String begin6 = DateUtil.formatDateTime(dayBegin6);
        Date dayEnd6 = DateUtil.offsetDay(dayEnd, -6);
        String end6 = DateUtil.formatDateTime(dayEnd6);
        List<Float> dayAverage6 = getDayAverage(begin6, end6, aquariumId);

        //7天的每天平均ph
        List<Float> value1s = new ArrayList<>();
        value1s.add(dayAverage.get(0));
        value1s.add(dayAverage1.get(0));
        value1s.add(dayAverage2.get(0));
        value1s.add(dayAverage3.get(0));
        value1s.add(dayAverage4.get(0));
        value1s.add(dayAverage5.get(0));
        value1s.add(dayAverage6.get(0));
        Collections.reverse(value1s);

        //7天的每天平均温度
        List<Float> value2s = new ArrayList<>();
        value2s.add(dayAverage.get(1));
        value2s.add(dayAverage1.get(1));
        value2s.add(dayAverage2.get(1));
        value2s.add(dayAverage3.get(1));
        value2s.add(dayAverage4.get(1));
        value2s.add(dayAverage5.get(1));
        value2s.add(dayAverage6.get(1));
        Collections.reverse(value2s);

        //7天的每天平均电导率
        List<Float> value3s = new ArrayList<>();
        value3s.add(dayAverage.get(2));
        value3s.add(dayAverage1.get(2));
        value3s.add(dayAverage2.get(2));
        value3s.add(dayAverage3.get(2));
        value3s.add(dayAverage4.get(2));
        value3s.add(dayAverage5.get(2));
        value3s.add(dayAverage6.get(2));
        Collections.reverse(value3s);

        //7天的每天平均浑浊度
        List<Float> value4s = new ArrayList<>();
        value4s.add(dayAverage.get(3));
        value4s.add(dayAverage1.get(3));
        value4s.add(dayAverage2.get(3));
        value4s.add(dayAverage3.get(3));
        value4s.add(dayAverage4.get(3));
        value4s.add(dayAverage5.get(3));
        value4s.add(dayAverage6.get(3));
        Collections.reverse(value4s);

        //7天的每天平均溶解氧
        List<Float> value5s = new ArrayList<>();
        value5s.add(dayAverage.get(4));
        value5s.add(dayAverage1.get(4));
        value5s.add(dayAverage2.get(4));
        value5s.add(dayAverage3.get(4));
        value5s.add(dayAverage4.get(4));
        value5s.add(dayAverage5.get(4));
        value5s.add(dayAverage6.get(4));
        Collections.reverse(value5s);

        List<String> listWeek = new ArrayList<>();
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};

        //返回横坐标日期
        Calendar calendar = Calendar.getInstance();
        //今天星期几对应的数字
        int today = calendar.get(Calendar.DAY_OF_WEEK);
        for (int i = 0; i < 7; i++) {
            if (today - i <= 0) {
                listWeek.add(weekDays[today - i + 7 - 1]);
            } else {
                listWeek.add(weekDays[today - i - 1]);
            }

        }
        Collections.reverse(listWeek);


        return R.ok().data("ph", value1s).data("wendu", value2s).data("diandao", value3s).data("hunzhuo", value4s).data("rongJieYang", value5s).data("listWeek", listWeek);
    }

    //获取某一天平均ph、温度、电导率、浑浊度
    public List<Float> getDayAverage(String begin, String end, Long aquariumId) {
        List<SensorData> list = sensorDataService.list(new QueryWrapper<SensorData>().eq("a_id", aquariumId).ge("gmt_create", begin).le("gmt_create", end));

        int len = list.size();
        //一天总ph
        float v1s = 0;
        //一天总温度
        float v2s = 0;
        //一天总电导率
        float v3s = 0;
        //一天总浑浊度
        float v4s = 0;
        //一天总溶解氧
        float v5s = 0;

        for (SensorData sensorDate : list) {
            v1s += Float.valueOf(sensorDate.getValue1());
            v2s += Float.valueOf(sensorDate.getValue2());
            v3s += Float.valueOf(sensorDate.getValue3());
            v4s += Float.valueOf(sensorDate.getValue4());
            v5s += Float.valueOf(sensorDate.getValue5());
        }
        //平均ph值
        float v1 = (float) Math.round(v1s / len * 100) / 100;
        //平均温度
        float v2 = (float) Math.round(v2s / len * 100) / 100;
        //平均电导率
        float v3 = (float) Math.round(v3s / len * 100) / 100;
        //平均浑浊度
        float v4 = (float) Math.round(v4s / len * 100) / 100;
        //平均溶解氧
        float v5 = (float) Math.round(v5s / len * 100) / 100;

        List<Float> resList = new ArrayList<>();
        resList.add(v1);
        resList.add(v2);
        resList.add(v3);
        resList.add(v4);
        resList.add(v5);
        return resList;
    }

}
